/*
 * WRITING TESTS IN EXTERNAL HEADER FILES AND INCLUDING THEM IN
 * THE MAIN FUNCTION WORKS AUTOMATICALLY WITH NO FURTHER CODE NEEDED
 */
#ifndef TEXTCHUNKTESTS
#define TEXTCHUNKTESTS
#include <iostream>
#include <fstream>
using namespace std;
#include "TextChunk.h"
#include <gtest/gtest.h>

TEST(TextChunkTest, StringArrayTest)
{
	cerr << "START StringArrayTest" << endl;
	
	/*
	 * --------BEGIN TEST PREPARATION--------
	 */
		//manual string parameters
		string TITLE("title");
		string AUTHOR("author");
		string DESCRIPTION("description");
		string COPYRIGHT("copyright");
		string CREATION_TIME("creation time");
		string SOFTWARE("software");
		string DISCLAIMER("disclaimer");
		string SOURCE("source");
		string COMMENT("comment");
		//end manual string parameters
		
	string** strARRAY = new string*[9];
	for(int i = 0; i < 9; i++)
	{
		strARRAY[i] = new string[1];
	}
	strARRAY[0][0] = TITLE;
	strARRAY[1][0] = AUTHOR;
	strARRAY[2][0] = DESCRIPTION;
	strARRAY[3][0] = COPYRIGHT;
	strARRAY[4][0] = CREATION_TIME;
	strARRAY[5][0] = SOFTWARE;
	strARRAY[6][0] = DISCLAIMER;
	strARRAY[7][0] = SOURCE;
	strARRAY[8][0] = COMMENT;
	
	/*
	 * --------END TEST PREPARATION--------
	 */
	
	cerr << "Begin initialize TextChunk object" << endl;
		//begin test array TextChunk
		TextChunk* textChunk = new TextChunk(strARRAY);
	cerr << "End initialize TextChunk object" << endl;
		//CTOR should have copied the array- retrieve the internal
		//copy with getAllStrings()
		string** internalArray = textChunk->getAllStrings();
		
		//check the internal copy against the test creation
		for(int i = 0; i < 9; i++)
		{
			//check the internal C++ array against the one passed
			//in the CTOR
			ASSERT_TRUE(strARRAY[i][0] == internalArray[i][0]);	
		}
		
		//delete the object and re-use the pointer
		delete textChunk;
		
		/*
		 * --------BEGIN TESTING 2ND CTOR OF class TextChunk--------
		 */
		//make new object with the same pointer
		textChunk = new TextChunk(&TITLE, &AUTHOR, &DESCRIPTION, &COPYRIGHT,
							&CREATION_TIME, &SOFTWARE, &DISCLAIMER,
							&SOURCE, &COMMENT);
		//get the internal array and run it through a loop
		//with assertions
		internalArray = textChunk->getAllStrings();
		
		for(int i = 0; i < 9; i++)
		{
			ASSERT_TRUE(strARRAY[i][0] == internalArray[i][0]);
		}
		
	/*
	 * --------END TESTING 2ND CTOR OF class TextChunk--------
	 */
		
	//delete the last object
	delete textChunk;
		
	//delete the array
	for(int i = 0; i < 9; i++)
	{
		delete[] strARRAY[i];
	}
	delete[] strARRAY;
}


/**
 * will write a default resource file for TextChunk
 * for testing purposes
 * this function can't do ASSERT's or use the framework,
 * so it has a bool return instead and prints an error
 * message before returning
 */
bool writeDefaultFile()
{
	//write misc. values to the file
	string** defaultStrings = new string*[9];
	for(int i = 0; i < 9; i++)
	{
		defaultStrings[i] = new string[1];
	}
	defaultStrings[0][0] = "testImg";
	defaultStrings[1][0] = "testAuthor";
	defaultStrings[2][0] = "testDescription";
	defaultStrings[3][0] = "testCopyright";
	defaultStrings[4][0] = "testCreationTime";
	defaultStrings[5][0] = "testSoftware";
	defaultStrings[6][0] = "testDisclaimer";
	defaultStrings[7][0] = "testSource";
	defaultStrings[8][0] = "testComment";
	
	//open an output stream to write the strings to disk
	ofstream out(TextChunk::defaultsFilename.c_str());
	//fail the test if the file isn't open
	if(!out.is_open())
	{
		cerr << "FILE COULD NOT OPEN" << endl;
		return false;
	}
	
	//if its no good...
	if(!out.good())
	{
		cerr << "CANNOT WRITE TO FILE" << endl;
		return false;
	}
	
	//write the entire array to the example file
	for(int i = 0; i < 9; i++)
	{
		out << defaultStrings[i][0];
	}
	
	if(out.bad())
	{
		cerr << "STREAM IS BAD" << endl;
		return false;
	}
	
	if(out.is_open())
	{
		out.close();
	}
	else
	{
		cerr << "COULD NOT CLOSE STREAM" << endl;
		return false;
	}
	
	for(int x = 0; x < 9; x++)
	{
		delete[] defaultStrings[x];
	}
	delete[] defaultStrings;
	
	return true;
}

/**
 * READ IN SETTINGS FROM A FILE AND CONSTRUCT A TextChunk OBJECT
 */
TEST(TextChunkTest, ReadFileTest)
{
	//we'll write example data to a file if it doesn't exist
	ifstream in(TextChunk::defaultsFilename.c_str());
	bool isOpen = in.is_open();
	if(!isOpen)
	{
		ASSERT_TRUE(writeDefaultFile());
		in.open(TextChunk::defaultsFilename.c_str());
	}
	
	//if it won't open after writing the default file,
	//fail the test
	if(!in.is_open())
	{
		ASSERT_TRUE(false);
	}
	
	/*
	 * Create and initialize an array to hold
	 * data read from the file
	 */
	string** strArray = new string*[9];
	for(int i = 0; i < 9; i++)
	{
		strArray[i] = new string[1];
	}
	//end creating array
	
	//read in the file into the array
	for(int i = 0; i < 9; i++)
	{
		in >> strArray[i][0];
	}
	
	//create a TextChunk object using the same file with
	//the static function being tested
	//if it has the same internal array independently as the one
	//read from the file, it created the object correctly
	TextChunk textChunk = 
				TextChunk::readTextChunk(&TextChunk::defaultsFilename);
	string** internalArray = textChunk.getAllStrings();
	
	//test the internal array against the one already read from the file...
	for(int i = 0; i < 9; i++)
	{
		ASSERT_TRUE(strArray[i][0] == internalArray[i][0]);
	}
				
	//delete the string array
	for(int x = 0; x < 9; x++)
	{
		delete[] strArray[x];
	}
	delete[] strArray;
	
	//close the input stream if its open, or fail the test if its not
	if(in.is_open())
	{
		in.close();
	}
	else
	{
		ASSERT_TRUE(false);
	}
}

#endif